package org.stvd.core.util.json;
import java.security.Timestamp;
import java.util.List;

import net.sf.ezmorph.object.DateMorpher;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import net.sf.json.JsonConfig;
import net.sf.json.util.JSONUtils;
import net.sf.json.util.PropertySetStrategy;

/**
 * @author Shengzhao Li
 */
public final class JsonUtils {

    public static <T> T textToBean(T expectInstance, String jsonText) {
        return textToBean(expectInstance, jsonText, JavaPropertySetStrategy.INSTANCE);
    }

    @SuppressWarnings("unchecked")
    public static <T> T textToBean(T expectInstance, String jsonText, JsonConfig jsonConfig) {
        final JSONObject jsonObject = JSONObject.fromObject(jsonText);
        String[] dateFormats = new String[] {"yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss" };
        JSONUtils.getMorpherRegistry().registerMorpher(new DateMorpher(dateFormats));
        return (T) JSONObject.toBean(jsonObject, jsonConfig);
    }

    @SuppressWarnings("unchecked")
    public static <T> T textToBean(T expectInstance, String jsonText, PropertySetStrategy propertySetStrategy) {
        final JsonConfig jsonConfig = new JsonConfig();
        jsonConfig.setRootClass(expectInstance.getClass());
        jsonConfig.setPropertySetStrategy(propertySetStrategy);

        final JSONObject jsonObject = JSONObject.fromObject(jsonText);
        return (T) JSONObject.toBean(jsonObject, jsonConfig);
    }

    @SuppressWarnings("unchecked")
    public static <T> T textToBean(T expectInstance, String jsonText, CustomJsonConfigurer jsonConfigurer) {
        final JsonConfig jsonConfig = new JsonConfig();
        jsonConfig.setRootClass(expectInstance.getClass());
        jsonConfig.setPropertySetStrategy(JavaPropertySetStrategy.INSTANCE);
        // callback
        jsonConfigurer.config(jsonConfig);

        final JSONObject jsonObject = JSONObject.fromObject(jsonText);
        return (T) JSONObject.toBean(jsonObject, jsonConfig);
    }

    @SuppressWarnings("unchecked")
    public static <T> List<T> textToBeanList(T expectInstance, String jsonText) {
        final JsonConfig jsonConfig = new JsonConfig();
        jsonConfig.setRootClass(expectInstance.getClass());
        jsonConfig.setPropertySetStrategy(JavaPropertySetStrategy.INSTANCE);
        String[] dateFormats = new String[] {"yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss" };
        JSONUtils.getMorpherRegistry().registerMorpher(new DateMorpher(dateFormats));
        final JSONArray jsonArray = JSONArray.fromObject(jsonText);
        return JSONArray.toList(jsonArray, expectInstance, jsonConfig);
    }

    public static <T> String beanToText(T object) {
        final JSONObject jsonObject = JSONObject.fromObject(object);
        return jsonObject.toString();
    }

    public static String coverToJson(Object object) {
        if (object == null) {
            return null;
        }
        JsonConfig config = new JsonConfig();
        config.registerJsonValueProcessor(java.sql.Date.class, new JsonDateValueProcessor("yyyy-MM-dd"));
        config.registerJsonValueProcessor(Timestamp.class, new JsonDateValueProcessor("yyyy-MM-dd HH:mm:ss"));
        config.registerJsonValueProcessor(java.util.Date.class, new JsonDateValueProcessor("yyyy-MM-dd HH:mm:ss"));
        // config.setJsonPropertyFilter(new PropertyFilter() {
        // public boolean apply(Object source, String name, Object value) {
        // if (((source instanceof LazyInitializer)) || ((value instanceof
        // LazyInitializer)))
        // return true;
        // if ((!Hibernate.isInitialized(source)) ||
        // (!Hibernate.isInitialized(value)))
        // return true;
        // return false;
        // }
        // });
        try {
            if (object instanceof List) {
                return JSONArray.fromObject(object, config).toString();
            } else {
                return JSONObject.fromObject(object, config).toString();
            }
        } catch (Exception ex) {
            return object.toString();
        }
    }

    private JsonUtils() {
    }

}